package com.flame.shapeville.controller;

import com.flame.shapeville.bean.Course;
import com.flame.shapeville.bean.Exercise;
import com.flame.shapeville.bean.Task;
import com.flame.shapeville.bean.User;
import com.flame.shapeville.enums.SceneStyle;
import com.flame.shapeville.factory.BeanFactory;
import com.flame.shapeville.service.TaskService;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.util.Duration;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Controller responsible for managing the main scene of the application.
 * <p>
 * Displays user progress, current task information, and allows navigation between tasks.
 *
 * @author Flame Dev Team
 * @version 1.0
 * @since 2025-05-01
 */
public class MainController implements JfController {

    /**
     * Label displaying the username.
     */
    @FXML
    private Label username;

    /**
     * Label displaying the current course name.
     */
    @FXML
    private Label courseName;

    /**
     * Label displaying the current task name.
     */
    @FXML
    private Label taskName;

    /**
     * ImageView for moon icon (basic task status).
     */
    @FXML
    private ImageView moon;

    /**
     * Label showing basic task completion progress.
     */
    @FXML
    private Label basicProgress;

    /**
     * ImageView for sun icon (advanced task status).
     */
    @FXML
    private ImageView sun;

    /**
     * Label showing advanced task completion progress.
     */
    @FXML
    private Label advancedProgress;

    /**
     * ProgressBar showing overall course progress.
     */
    @FXML
    private ProgressBar progressBar;

    /**
     * Label showing percentage of overall progress.
     */
    @FXML
    private Label progressPercent;

    /**
     * Tooltip showing fraction of completed exercises.
     */
    @FXML
    private Tooltip progressFraction;

    /**
     * Button to navigate to the previous task.
     */
    @FXML
    private Button prevTask;

    /**
     * Button to navigate to the next task.
     */
    @FXML
    private Button nextTask;

    /**
     * Parent node containing the score display.
     */
    @FXML
    private Parent score;

    /**
     * Controller for the score display.
     */
    @FXML
    private ScoreController scoreController;

    // Icons for different states
    private Image moonD = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/static/images/moon_d.png")));
    private Image moonL = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/static/images/moon_l.png")));
    private Image sunD = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/static/images/sun_d.png")));
    private Image sunL = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/static/images/sun_l.png")));

    /**
     * List of tasks in the current course.
     */
    private List<Task> taskList;

    /**
     * Map of tasks to their exercises.
     */
    private Map<Task, List<Exercise>> exerciseMap;

    /**
     * Current index of the selected task.
     */
    private int taskPointer = 0;

    /**
     * Initializes the controller with user and course data.
     */
    @Override
    public void init() {
        User user = (User) BeanFactory.getBean("user");
        Course course = (Course) BeanFactory.getBean("curCourse");

        username.setText(user.getName());
        courseName.setText(course.getName());

        TaskService taskService = (TaskService) BeanFactory.getBean("taskService");
        taskList = taskService.loadTask(user.getId(), course.getId());

        initTask();
        initScore();
        initProgress();
        setTask();
        flushSwitchButton();
    }

    /**
     * Sets the initial task pointer based on completion status.
     */
    private void initTask() {
        boolean continueSign = true;
        for (Task task : taskList) {
            if (task.isCompleted() && continueSign) {
                taskPointer++;
            } else {
                continueSign = false;
            }
        }
        setTask();
    }

    /**
     * Initializes the score controller.
     */
    private void initScore() {
        scoreController.init();
    }

    /**
     * Updates the progress bar and labels based on completed exercises.
     */
    private void initProgress() {
        int completeNum = 0;
        int totalNum = 0;
        for (Task task : taskList) {
            completeNum += task.getCompleteCount();
            totalNum += task.getBasicCount() + task.getAdvancedCount();
        }
        progressBar.setProgress(completeNum * 1.0 / totalNum);
        progressPercent.setText(Math.round(completeNum * 100.0 / totalNum) + "%");
        progressFraction.setShowDelay(Duration.millis(100));
        progressFraction.setText(completeNum + "/" + totalNum);
    }

    /**
     * Shows the score panel.
     */
    @FXML
    private void showScore() {
        score.setVisible(true);
        score.setDisable(false);
    }

    /**
     * Goes to the previous task.
     */
    @FXML
    private void prevTask() {
        taskPointer = Math.max(0, taskPointer - 1);
        setTask();
        flushSwitchButton();
    }

    /**
     * Goes to the next task.
     */
    @FXML
    private void nextTask() {
        taskPointer = Math.min(taskList.size() - 1, taskPointer + 1);
        setTask();
        flushSwitchButton();
    }

    /**
     * Updates button states based on current task position.
     */
    private void flushSwitchButton() {
        prevTask.setDisable(taskPointer == 0);
        prevTask.setVisible(taskPointer != 0);
        nextTask.setDisable(taskPointer == taskList.size() - 1);
        nextTask.setVisible(taskPointer != taskList.size() - 1);
    }

    /**
     * Updates UI to reflect current task data.
     */
    private void setTask() {
        Task curTask = taskList.get(taskPointer);
        taskName.setText(curTask.getName());
        BeanFactory.setBean("curTask", curTask);

        if (curTask.isBasicCompleted()) {
            moon.setImage(moonL);
        } else {
            moon.setImage(moonD);
        }

        if (curTask.isAdvancedCompleted()) {
            sun.setImage(sunL);
        } else {
            sun.setImage(sunD);
        }

        basicProgress.setText(curTask.getBasicCorrectCount() + "/" + curTask.getBasicCount());
        advancedProgress.setText(curTask.getAdvancedCorrectCount() + "/" + curTask.getAdvancedCount());
    }

    /**
     * Starts the current task.
     */
    @FXML
    private void startTask() {
        SceneController.setSceneStyle(SceneStyle.TASK);
    }

    /**
     * Returns to the course selection screen.
     */
    @FXML
    private void returnCourse() {
        SceneController.setSceneStyle(SceneStyle.COURSE);
    }
}
